home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / lfslib / stableMem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-17  |  12.2 KB  |  433 lines

  1. /* 
  2.  * stableMem.c --
  3.  *
  4.  *    Routines for access LFS stable memory data structure
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.3 90/01/12 12:03:36 douglis Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include "lfslib.h"
  21. #include "lfslibInt.h"
  22. #ifdef _HAS_PROTOTYPES
  23. #include <varargs.h>
  24. #include <sys/types.h>
  25. #endif /* _HAS_PROTOTYPES */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <bstring.h>
  29.  
  30. /*
  31.  * Data structure internal to the stable memory module.
  32.  */
  33. typedef struct StableMem {
  34.     Lfs            *lfsPtr;     /* File system. */
  35.     LfsStableMemParams  *paramsPtr;  /* Parameters of stable memory. */
  36.     LfsStableMemCheckPoint *checkpointPtr;  /* Checkpoint pointer. */
  37.     char        *dataPtr;        /* Memory hold stable data. */
  38.     int            *dirtyBlocksBitMap;    /* Bitmap of modified blocks. */
  39.     int            *layoutBlocksBitMap;   /* Bitmap of blocks layed out. */
  40. } StableMem;
  41.  
  42. /*
  43.  *----------------------------------------------------------------------
  44.  *
  45.  * LfsLoadStableMem --
  46.  *
  47.  *    Load a stable memory data structure
  48.  *
  49.  * Results:
  50.  *    A clientdata that can be used to access stable mem.
  51.  *
  52.  * Side effects:
  53.  *    None.
  54.  *
  55.  *----------------------------------------------------------------------
  56.  */
  57. ClientData 
  58. LfsLoadStableMem(lfsPtr, smemParamsPtr, cpPtr)
  59.     Lfs    *lfsPtr;    /*  file system. */
  60.     LfsStableMemParams  *smemParamsPtr;  /* Parameters of stable memory. */
  61.     LfsStableMemCheckPoint *cpPtr;  /* Checkpoint pointer. */
  62. {
  63.     int arraySize;
  64.     char *dataPtr;
  65.     StableMem *stableMemPtr;
  66.     int    *indexPtr, i;
  67.  
  68.     arraySize = smemParamsPtr->blockSize * smemParamsPtr->maxNumBlocks;
  69.     dataPtr = calloc(1, arraySize);
  70.     stableMemPtr = (StableMem *) malloc(sizeof(StableMem));
  71.     stableMemPtr->lfsPtr = lfsPtr;
  72.     stableMemPtr->paramsPtr = smemParamsPtr;
  73.     stableMemPtr->checkpointPtr = 
  74.     (LfsStableMemCheckPoint *) malloc(sizeof(LfsStableMemCheckPoint) +
  75.             smemParamsPtr->maxNumBlocks * sizeof(int));
  76.     bcopy((char *) cpPtr, (char *) stableMemPtr->checkpointPtr, 
  77.         sizeof(LfsStableMemCheckPoint) + 
  78.         sizeof(int) * cpPtr->numBlocks);
  79.     indexPtr = (int *) (stableMemPtr->checkpointPtr+1);
  80.     for (i = cpPtr->numBlocks; i < smemParamsPtr->maxNumBlocks; i++) {
  81.     indexPtr[i] = FSDM_NIL_INDEX;
  82.     }
  83.     stableMemPtr->dataPtr = dataPtr;
  84.     stableMemPtr->dirtyBlocksBitMap = (int *) NIL;
  85.     stableMemPtr->layoutBlocksBitMap = (int *) NIL;
  86.     return (ClientData) stableMemPtr;
  87. }
  88.  
  89. /*
  90.  *----------------------------------------------------------------------
  91.  *
  92.  * LfsGetStableMemEntry --
  93.  *
  94.  *    Return a pointer to a specified stable memory entry.
  95.  *
  96.  * Results:
  97.  *    A pointer to the stable memory entry request, NIL if entry doesn't
  98.  *    exist.
  99.  *
  100.  * Side effects:
  101.  *    None.
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105.  
  106. char *
  107. LfsGetStableMemEntry(clientData, entryNumber)
  108.     ClientData clientData;
  109.     int entryNumber;
  110. {
  111.     StableMem *stableMemPtr = (StableMem *) clientData;
  112.     LfsStableMemBlockHdr *hdrPtr;
  113.     int blockNum, offset;
  114.     int    blockIndex;
  115.  
  116.     if ((entryNumber < 0) || 
  117.     (entryNumber >= stableMemPtr->paramsPtr->maxNumEntries)) {
  118.     fprintf(stderr,"Bad stable memory entry number %d\n", entryNumber);
  119.     return (char *) NULL;
  120.     }
  121.     blockNum = entryNumber / stableMemPtr->paramsPtr->entriesPerBlock;
  122.     offset = (entryNumber % stableMemPtr->paramsPtr->entriesPerBlock) * 
  123.         stableMemPtr->paramsPtr->entrySize + 
  124.            sizeof(LfsStableMemBlockHdr);
  125.     hdrPtr = (LfsStableMemBlockHdr *) (stableMemPtr->dataPtr + 
  126.         blockNum * stableMemPtr->paramsPtr->blockSize);
  127.     if (hdrPtr->magic != LFS_STABLE_MEM_BLOCK_MAGIC) {
  128.     blockIndex = LfsGetStableMemBlockIndex(clientData, blockNum);
  129.     if (blockIndex != FSDM_NIL_INDEX) {
  130.         if (LfsDiskRead(stableMemPtr->lfsPtr, blockIndex, 
  131.             stableMemPtr->paramsPtr->blockSize, (char *) hdrPtr) != 
  132.         stableMemPtr->paramsPtr->blockSize) { 
  133.             fprintf(stderr, "%s:Can't read at %d\n", stableMemPtr->lfsPtr->deviceName, 
  134.                 blockIndex);
  135.         }
  136.     } else {
  137.         bzero((char *) hdrPtr, stableMemPtr->paramsPtr->blockSize);
  138.         hdrPtr->magic = LFS_STABLE_MEM_BLOCK_MAGIC;
  139.         hdrPtr->memType = stableMemPtr->paramsPtr->memType;
  140.         hdrPtr->blockNum = blockNum;
  141.     }
  142.     }
  143.  
  144.     return stableMemPtr->dataPtr + 
  145.         blockNum * stableMemPtr->paramsPtr->blockSize + offset;
  146. }
  147.  
  148. /*
  149.  *----------------------------------------------------------------------
  150.  *
  151.  * LfsGetStableMemBlockIndex --
  152.  *
  153.  *    Return the BlockIndex into the disk of the stable memory block.
  154.  *
  155.  * Results:
  156.  *    The disk address. FSDM_NIL)INDEX if block doesn't exist.
  157.  *
  158.  * Side effects:
  159.  *    None.
  160.  *
  161.  *----------------------------------------------------------------------
  162.  */
  163.  
  164. extern int
  165. LfsGetStableMemBlockIndex(clientData, blockNum)
  166.     ClientData clientData;
  167.     int blockNum;
  168. {
  169.     StableMem *stableMemPtr = (StableMem *) clientData;
  170.     int *blockIndexPtr;
  171.  
  172.     if ((blockNum < 0) || 
  173.     (blockNum >= stableMemPtr->paramsPtr->maxNumBlocks)) {
  174.     fprintf(stderr,"Bad stable memory block num %d\n", blockNum);
  175.     return FSDM_NIL_INDEX;
  176.     }
  177.     blockIndexPtr = (int *)((char *) (stableMemPtr->checkpointPtr) + sizeof(LfsStableMemCheckPoint));
  178.     return blockIndexPtr[blockNum];
  179. }
  180.  
  181.  
  182. /*
  183.  *----------------------------------------------------------------------
  184.  *
  185.  * LfsMarkStableMemEntryDirty --
  186.  *
  187.  *    Mark a stable memory entry as being modified.
  188.  *
  189.  * Results:
  190.  *    None.
  191.  *
  192.  * Side effects:
  193.  *    None.
  194.  *
  195.  *----------------------------------------------------------------------
  196.  */
  197.  
  198. void
  199. LfsMarkStableMemEntryDirty(clientData, entryNumber)
  200.     ClientData clientData;
  201.     int entryNumber;
  202. {
  203.     StableMem *stableMemPtr = (StableMem *) clientData;
  204.     int blockNum;
  205.  
  206.     if ((entryNumber < 0) || 
  207.     (entryNumber >= stableMemPtr->paramsPtr->maxNumEntries)) {
  208.     fprintf(stderr,"Bad stable memory entry number %d\n", entryNumber);
  209.     return;
  210.     }
  211.     blockNum = entryNumber / stableMemPtr->paramsPtr->entriesPerBlock;
  212.     if (stableMemPtr->dirtyBlocksBitMap == (int *) NIL) {
  213.     Bit_Alloc(stableMemPtr->paramsPtr->maxNumBlocks, 
  214.             stableMemPtr->dirtyBlocksBitMap);
  215.     }
  216.     Bit_Set(blockNum, stableMemPtr->dirtyBlocksBitMap);
  217.  
  218.     return;
  219. }
  220.  
  221.  
  222. /*
  223.  *----------------------------------------------------------------------
  224.  *
  225.  * LfsSetStableMemBlockIndex --
  226.  *
  227.  *    Change the block index of a stable mem block.
  228.  *
  229.  * Results:
  230.  *    None.
  231.  *
  232.  * Side effects:
  233.  *    None.
  234.  *
  235.  *----------------------------------------------------------------------
  236.  */
  237.  
  238. void
  239. LfsSetStableMemBlockIndex(clientData, blockNum, diskAddr)
  240.     ClientData clientData;
  241.     int blockNum;
  242.     int    diskAddr;
  243. {
  244.     StableMem *stableMemPtr = (StableMem *) clientData;
  245.     int *blockIndexPtr;
  246.  
  247.     if ((blockNum < 0) || 
  248.     (blockNum >= stableMemPtr->paramsPtr->maxNumBlocks)) {
  249.     panic(stderr,"Bad stable memory block num %d\n", blockNum);
  250.     return;
  251.     }
  252.     blockIndexPtr = (int *)((char *) (stableMemPtr->checkpointPtr) + sizeof(LfsStableMemCheckPoint));
  253.  
  254.     LfsSegUsageAdjustBytes(stableMemPtr->lfsPtr, blockIndexPtr[blockNum], 
  255.         -stableMemPtr->paramsPtr->blockSize);
  256.  
  257.     blockIndexPtr[blockNum] = diskAddr;
  258.     if (blockNum > stableMemPtr->checkpointPtr->numBlocks) {
  259.     stableMemPtr->checkpointPtr->numBlocks = blockNum+1;
  260.     }
  261.     return;
  262. }
  263.  
  264.  
  265.  
  266.  
  267. static Boolean AddBlockToSegment _ARGS_((
  268.     Address address, int blockNum, StableMem *stableMemPtr,LfsSeg *segPtr));
  269.  
  270.  
  271. /*
  272.  *----------------------------------------------------------------------
  273.  *
  274.  * AddBlockToSegment --
  275.  *
  276.  *    Add a metadata block to the specified segment.
  277.  *
  278.  * Results:
  279.  *    TRUE if segment is full so we couldn't add block.
  280.  *
  281.  * Side effects:
  282.  *    None.
  283.  *
  284.  *----------------------------------------------------------------------
  285.  */
  286.  
  287.  
  288. static Boolean
  289. AddBlockToSegment(address, blockNum,  stableMemPtr, segPtr)
  290.     Address      address;    /* Address of block. */
  291.     int        blockNum;    /* Block number. */
  292.     StableMem *stableMemPtr;    /* Stable mem. */
  293.     LfsSeg *segPtr;        /* Segment to place data blocks in. */
  294. {
  295.     int    fsBlocks;
  296.     char *summaryPtr;
  297.     LfsSegElement *bufferPtr;
  298.  
  299.     fsBlocks =  stableMemPtr->paramsPtr->blockSize/LfsBlockSize(segPtr->lfsPtr);
  300.     summaryPtr = LfsSegGrowSummary(segPtr, fsBlocks, sizeof(int));
  301.     if (summaryPtr == (char *)NIL) {
  302.     return TRUE;
  303.     }
  304.     bufferPtr = LfsSegAddDataBuffer(segPtr, fsBlocks, address,
  305.                 (ClientData) blockNum);
  306.     if (stableMemPtr->paramsPtr->memType == LFS_SEG_USAGE_MOD) { 
  307.     segPtr->lfsPtr->pstats.segUsageBlockWrite++;
  308.     } else {
  309.     segPtr->lfsPtr->pstats.descMapBlockWrite++;
  310.     }
  311.  
  312.     *(int *)summaryPtr = blockNum;
  313.     LfsSegSetSummaryPtr(segPtr,summaryPtr + sizeof(int));
  314.     LfsSetStableMemBlockIndex((ClientData) (stableMemPtr), blockNum, 
  315.             LfsSegDiskAddress(segPtr, bufferPtr));
  316.  
  317.     segPtr->activeBytes += stableMemPtr->paramsPtr->blockSize;
  318.     return FALSE;
  319. }
  320.  
  321.  
  322.  
  323. /*
  324.  *----------------------------------------------------------------------
  325.  *
  326.  * LfsStableMemCheckpoint --
  327.  *
  328.  *    Routine to handle writing of data for this module.
  329.  *
  330.  * Results:
  331.  *    TRUE if more data needs to be written, FALSE if this module is
  332.  *    checkpointed.
  333.  *
  334.  * Side effects:
  335.  *    Many
  336.  *
  337.  *----------------------------------------------------------------------
  338.  */
  339.  
  340. Boolean
  341. LfsStableMemCheckpoint(segPtr,  checkPointPtr, checkPointSizePtr, clientData)
  342.     LfsSeg *segPtr;        /* Segment to place data blocks in. */
  343.     char   *checkPointPtr;      /* Buffer to write checkpoint data. */
  344.     int       *checkPointSizePtr;  /* Bytes added to the checkpoint area.*/
  345.     ClientData    clientData;
  346. {
  347.     StableMem *stableMemPtr = (StableMem *) clientData;
  348.     Boolean    full = FALSE;
  349.     int        blockNum;
  350.     char    *bufPtr;
  351.  
  352.  
  353.     if (stableMemPtr->dirtyBlocksBitMap == (int *) NIL) {
  354.     return FALSE;
  355.     }
  356.     if (stableMemPtr->layoutBlocksBitMap == (int *) NIL) {
  357.     Bit_Alloc(stableMemPtr->paramsPtr->maxNumBlocks, 
  358.             stableMemPtr->layoutBlocksBitMap);
  359.     }
  360.  
  361.     blockNum = Bit_FindFirstSet(stableMemPtr->paramsPtr->maxNumBlocks,
  362.                 stableMemPtr->dirtyBlocksBitMap);
  363.     while(!full && (blockNum != -1)) { 
  364.     if (Bit_IsClear(blockNum, stableMemPtr->layoutBlocksBitMap)) {
  365.         bufPtr = stableMemPtr->dataPtr + 
  366.                 blockNum * stableMemPtr->paramsPtr->blockSize;
  367.         full = AddBlockToSegment(bufPtr, blockNum, stableMemPtr, segPtr);
  368.     }
  369.     if (!full) {
  370.         Bit_Set(blockNum, stableMemPtr->layoutBlocksBitMap);
  371.         Bit_Clear(blockNum, stableMemPtr->dirtyBlocksBitMap);
  372.         blockNum = Bit_FindFirstSet(stableMemPtr->paramsPtr->maxNumBlocks,
  373.                 stableMemPtr->dirtyBlocksBitMap);
  374.     } 
  375.  
  376.     }
  377.     if (!full) {
  378.     *(LfsStableMemCheckPoint *) checkPointPtr = 
  379.             *(stableMemPtr->checkpointPtr);
  380.     bcopy(((char *) (stableMemPtr->checkpointPtr) + 
  381.             sizeof(LfsStableMemCheckPoint)),
  382.         checkPointPtr + sizeof(LfsStableMemCheckPoint), 
  383.         sizeof(int) * stableMemPtr->checkpointPtr->numBlocks);
  384.     *checkPointSizePtr = sizeof(int) * stableMemPtr->checkpointPtr->numBlocks + 
  385.                 sizeof(LfsStableMemCheckPoint);
  386.  
  387.     }
  388.     return full;
  389. }
  390.  
  391.  
  392.  
  393. /*
  394.  *----------------------------------------------------------------------
  395.  *
  396.  * LfsStableMemWriteDone --
  397.  *
  398.  *    Routine to inform this module that a write has finished.
  399.  *
  400.  * Results:
  401.  *    None.
  402.  *
  403.  * Side effects:
  404.  *    Many
  405.  *
  406.  *----------------------------------------------------------------------
  407.  */
  408.  
  409. void
  410. LfsStableMemWriteDone(segPtr, flags, clientData)
  411.     LfsSeg *segPtr;    /* Segment whose write finishes. */
  412.     int        flags;    /* Write done flags. */
  413.     ClientData clientData;
  414. {
  415.     StableMem *stableMemPtr = (StableMem *) clientData;
  416.     int    blockNum;
  417.     LfsSegElement *bufferLimitPtr, *bufferPtr = LfsSegGetBufferPtr(segPtr);
  418.  
  419.     bufferLimitPtr = bufferPtr + LfsSegSummaryBytesLeft(segPtr) / sizeof(int);
  420.     while (bufferPtr < bufferLimitPtr) {
  421.     blockNum = (int) (bufferPtr->clientData);
  422.     Bit_Clear(blockNum, stableMemPtr->layoutBlocksBitMap);
  423.     bufferPtr++;
  424.     }
  425.     if (!Bit_AnySet(stableMemPtr->paramsPtr->maxNumBlocks,
  426.             stableMemPtr->layoutBlocksBitMap)) {
  427.     free((char *) stableMemPtr->layoutBlocksBitMap);
  428.     stableMemPtr->layoutBlocksBitMap = (int *) NIL;
  429.     }
  430.     LfsSegSetBufferPtr(segPtr, bufferPtr);
  431. }
  432.  
  433.